﻿namespace _09_TetrisWork
{
    internal class Game
    {
        bool isOver;
        long lastTime, currentTime, fixedTime;
        int speed, fps;
        ConsoleKeyInfo key;
        public Shape shape;
        Map map;
        public Random rand;
        int[] randArr;
        int packetIndex;
        int[] packet = new int[7];

        public Game()
        {
            Console.CursorVisible = false;
            isOver = false;
            speed = 1;
            fps = 100;
            map = new Map();
            rand = new Random();
            randArr = new int[7];
            for (int i = 0; i < randArr.Length; i++)
            {
                randArr[i] = rand.Next(0, 7);
            }
            
        }

        int BlockPacket(ref int[] packet,int packetIndex)
        {
            for (int i = 0; i < randArr.Length; i++)
            {
                randArr[i] = rand.Next(0, 7);
                packet[i] = randArr[i];
            }
            return packet[packetIndex++];
        }

        public void Play()
        {
            Init();
            lastTime = DateTime.Now.Ticks;
            fixedTime = DateTime.Now.Ticks;
            while (!isOver)
            {
                Input();
                Update();
                currentTime = DateTime.Now.Ticks;
                if (currentTime - fixedTime > 1000_0000 / speed)
                {
                    FixedUpdate();
                    fixedTime = DateTime.Now.Ticks;
                }
                if (currentTime - lastTime > 1000_0000 / fps)
                {
                    Render();
                    lastTime = DateTime.Now.Ticks;
                }
            }
            End();
        }

        void Init()
        {
            map.Init();
            SpawnShape(BlockPacket(ref packet,packetIndex));
        }
        void Input()
        {
            key = default;
            if (Console.KeyAvailable)
            {
                key = Console.ReadKey(true);
            }
            switch (key.Key)
            {
                case ConsoleKey.W://顺时针转
                    shape.Rotate(true);
                    break;
                case ConsoleKey.S://加速下落
                    if (!shape.CheckHit(Map.Type.Wall, 0, 1))
                    {
                        shape.SpeedUp();
                    }
                    break;
                case ConsoleKey.A://向左移动
                    if (!shape.CheckHit(Map.Type.Wall, -1, 0))
                    {
                        shape.Move(-1);
                    }
                    break;
                case ConsoleKey.D://向右移动
                    if (!shape.CheckHit(Map.Type.Wall, 1, 0))
                    {
                        shape.Move(1);
                    }
                    break;
                case ConsoleKey.Z://逆时针转da
                    shape.Rotate(false);
                    break;
                case ConsoleKey.Spacebar://直接下落
                    while (true)
                    {
                        if (!shape.CheckHit(Map.Type.Wall, 0, 1))
                        {
                            shape.Drop();
                            Update();
                        }
                        else
                        {
                            break;
                        }
                    }
                    break;
            }
        }
        void Update()
        {
            shape.Update();
        }
        void FixedUpdate()
        {
            if (!shape.CheckHit(Map.Type.Wall, 0, 1))
            {
                shape.Drop();
            }
            else
            {
                // 触底
                // 固化
                shape.Solidify();
                // 检测是否有应该消除的行
                map.ClearLine();
                // 生成新的方块
                SpawnShape(/*rand.Next(0, 7)*/BlockPacket(ref packet, packetIndex));
                if (shape.CheckHit(Map.Type.Wall, 0, 1) && shape.CheckHit(Map.Type.Wall, 0, 0))
                {
                    Console.Clear();
                    Console.WriteLine("GameOver");
                    Thread.Sleep(100000000);
                }
            }
        }
        void Render()
        {
            map.Render();
            shape.Render();
        }
        void End()
        {

        }

        public void SpawnShape(int type)
        {
            switch (type)
            {
                case 0:
                    shape = new Shape_I(ref map);
                    break;
                case 1:
                    shape = new Shape_J(ref map);
                    break;
                case 2:
                    shape = new Shape_L(ref map);
                    break;
                case 3:
                    shape = new Shape_O(ref map);
                    break;
                case 4:
                    shape = new Shape_S(ref map);
                    break;
                case 5:
                    shape = new Shape_T(ref map);
                    break;
                case 6:
                    shape = new Shape_Z(ref map);
                    break;
            }
        }
        

        // 如何随机生成方块
        // 如何让边框阻挡方块
        // 如何判断方块到底了 ->无法继续掉落
        // 如何让地图记录到底的方块
        // 如何消行 核心逻辑
    }
}
